package org.jeecg.modules.lab.items.record.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.cronJob.MyEnum;
import org.jeecg.common.cronJob.entity.LabCronJob;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.TokenServess;
import org.jeecg.modules.lab.cronJob.service.ILabCronJobService;
import org.jeecg.modules.lab.entrust.controller.LabWentrustController;
import org.jeecg.modules.lab.entrust.entity.LabEntrustItems;
import org.jeecg.modules.lab.entrust.entity.LabEntrustSample;
import org.jeecg.modules.lab.entrust.entity.LabItemsRecordReport;
import org.jeecg.modules.lab.entrust.entity.LabWentrust;
import org.jeecg.modules.lab.entrust.service.*;
import org.jeecg.modules.lab.items.record.service.ILabItemsRecordReportService;
import org.jeecg.modules.lab.items.vo.LabEntrustItemsIndexPage;
import org.jeecg.modules.lab.items.vo.LabItemsReportPage;
import org.jeecg.modules.lab.notify.entity.LabNotify;
import org.jeecg.modules.lab.notify.service.ILabNotifyService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;

/**
 * @Description: 项目检测记录_实验报告
 * @Author: jeecg-boot
 * @Date: 2023-10-20
 * @Version: V1.0
 */
@Api(tags = "实验报告")
@RestController
@RequestMapping("/items/report/labItemsRecordReport")
@Slf4j
public class LabItemsRecordReportController extends JeecgController<LabItemsRecordReport, ILabItemsRecordReportService> {
    @Autowired
    private ILabItemsRecordReportService labItemsRecordReportService;

    @Autowired
    private LabWentrustController labWentrustController;

    @Autowired
    private ILabWentrustService labEntrustService;

    @Autowired
    private ILabWsuperviseService labWsuperviseService;

    @Autowired
    private ILabEntrustSampleService labEntrustSampleService;

    @Autowired
    private ILabEntrustItemsService labEntrustItemsService;

    @Autowired
    private ILabEntrustItemsIndexService labEntrustItemsIndexService;

    @Autowired
    private ILabCronJobService labCronJobService;

    @Autowired
    private ILabNotifyService labNotifyService;
    /**
     * 注入线程池
     */
    @Resource(name = "executorService")
    private ExecutorService threadExecutor;


    /**
     * 分页列表查询
     *
     * @param labItemsRecordReport
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "实验报告-分页列表查询", notes = "实验报告-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<LabItemsRecordReport>> queryPageList(LabItemsRecordReport labItemsRecordReport,
                                                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                             @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                             HttpServletRequest req) {
        QueryWrapper<LabItemsRecordReport> queryWrapper = QueryGenerator.initQueryWrapper(labItemsRecordReport, req.getParameterMap());
        Page<LabItemsRecordReport> page = new Page<LabItemsRecordReport>(pageNo, pageSize);
        IPage<LabItemsRecordReport> pageList = labItemsRecordReportService.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param labItemsRecordReport
     * @return
     */
    @AutoLog(value = "实验报告-添加")
    @ApiOperation(value = "实验报告-添加", notes = "实验报告-添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody LabItemsRecordReport labItemsRecordReport) {
        labItemsRecordReportService.save(labItemsRecordReport);

        if (MyEnum.sync) {
            long time = new Date().getTime();
            LabCronJob job = new LabCronJob("lab_items_record_report", "0", time, 1);
            labCronJobService.save(job);
        }
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param labItemsRecordReport
     * @return
     */
    @AutoLog(value = "实验报告-编辑")
    @ApiOperation(value = "实验报告-编辑", notes = "实验报告-编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody LabItemsRecordReport labItemsRecordReport) {
        labItemsRecordReport.setSynFlag("1");
        labItemsRecordReportService.updateById(labItemsRecordReport);

        if (MyEnum.sync) {
            long time = new Date().getTime();
            LabCronJob job = new LabCronJob("lab_items_record_report", "1", time, 1);
            labCronJobService.save(job);
        }
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "验报告-通过id删除")
    @ApiOperation(value = "实验报告-通过id删除", notes = "实验报告-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        labItemsRecordReportService.removeById(id);

        if (MyEnum.sync) {
            long time = new Date().getTime();
            String condition = "id='" + id + "'";
            LabCronJob job = new LabCronJob("lab_items_record_report", "2", condition, time, 1);
            labCronJobService.save(job);
        }
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "实验报告-批量删除")
    @ApiOperation(value = "实验报告-批量删除", notes = "实验报告-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.labItemsRecordReportService.removeByIds(Arrays.asList(ids.split(",")));

        if (MyEnum.sync) {
            long time = new Date().getTime();
            String[] split = ids.split(",");
            labCronJobService.saveCronBatch("lab_items_record_report", "2", time, split);
        }
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @ApiOperation(value = "实验报告-通过id查询", notes = "实验报告-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<LabItemsRecordReport> queryById(@RequestParam(name = "id", required = true) String id) {
        LabItemsRecordReport labItemsRecordReport = labItemsRecordReportService.getById(id);
        if (labItemsRecordReport == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(labItemsRecordReport);
    }


    /**
     * 实验报告_通过TaskId查询
     *
     * @param taskId
     * @param entrustType
     * @return
     */
    @ApiOperation(value = "实验报告_通过TaskId查询", notes = "实验报告_通过TaskId查询")
    @GetMapping(value = "/queryReportByTaskId")
    public Result<LabItemsReportPage> queryReportByTaskId(@RequestParam(name = "taskId", required = true) String taskId,
                                                          @RequestParam(name = "entrustType", required = true) String entrustType) {

        LabItemsReportPage labItemsReportPage = new LabItemsReportPage();

        LabWentrust labWentrust = labEntrustService.getById(taskId);

        //查询实验报告
        QueryWrapper<LabItemsRecordReport> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("task_id", taskId);
        LabItemsRecordReport labItemsRecordReport = labItemsRecordReportService.getOne(queryWrapper);
        //查询实验项目列表
        QueryWrapper<LabEntrustItems> queryItemWrapper = new QueryWrapper<>();
        queryItemWrapper.eq("entrust_id", taskId).eq("report_mark", "1").orderByAsc("item_name");
        List<LabEntrustItems> itemsList = labEntrustItemsService.list(queryItemWrapper);

        List<LabEntrustItemsIndexPage> labEntrustItemsIndexList = labEntrustItemsIndexService.getItemsIndexByTaskId(taskId);

        if (labItemsRecordReport == null) {
            QueryWrapper<LabEntrustSample> querySamWrapper = new QueryWrapper<>();
            querySamWrapper.eq("entrust_id", taskId).eq("sam_type", "主剂");
            List<LabEntrustSample> sample = labEntrustSampleService.list(querySamWrapper);
            if (sample != null) {
                String samNum = sample.get(0).getSamNum();
                if (samNum != null && !"".equals(samNum)) {
                    String num = samNum.substring(3, 6);
                    String year = String.valueOf(DateUtils.getYear());
                    if ("监督检验".equals(entrustType)) {
                        labItemsReportPage.setReportNum("(" + year + ") J" + " (" + num + ")");
                    } else if ("委托检验".equals(entrustType)) {
                        labItemsReportPage.setReportNum("(" + year + ") W" + " (" + num + ")");
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(itemsList)) {
                LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
                labItemsReportPage.setLabEntrustItemsIndexPageList(labEntrustItemsIndexList);
                LabEntrustItems item = itemsList.get(0);
                labItemsReportPage.setSamName(labWentrust.getSampleName());
                labItemsReportPage.setSamNum(item.getSamNum());
                labItemsReportPage.setBasisName(labWentrust.getExecuteBasisName());
                labItemsReportPage.setBasisNum(labWentrust.getExecuteBasisNum());
                labItemsReportPage.setReportDate(DateUtils.str2Date(DateUtils.getDate("yyyy-MM-dd"), new SimpleDateFormat("yyyy-MM-dd")));
                labItemsReportPage.setReportConcl("所检项目结果符合" + labWentrust.getExecuteBasisName() + labWentrust.getExecuteBasisNum() + "的标准规定。");
                labItemsReportPage.setTaskId(labWentrust.getId());
                labItemsReportPage.setCheckId(loginUser.getId());
                labItemsReportPage.setCheckName(loginUser.getRealname());
            }
        } else {
            if (CollectionUtil.isNotEmpty(itemsList)) {
                labItemsReportPage.setLabEntrustItemsIndexPageList(labEntrustItemsIndexList);
            }
            BeanUtils.copyProperties(labItemsRecordReport, labItemsReportPage);
        }
        return Result.OK(labItemsReportPage);
    }

    /**
     * 报告填报完成
     *
     * @param labItemsReportPage
     * @return
     */
    @AutoLog(value = "实验报告-报告填报完生成报告")
    @ApiOperation(value = "实验报告-报告填报完生成报告", notes = "实验报告-报告填报完生成报告")
    @RequestMapping(value = "/saveOrUpdateData", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<LabItemsReportPage> saveOrUpdateData(@RequestBody LabItemsReportPage labItemsReportPage) {

        LabItemsRecordReport itemsRecordReport = new LabItemsRecordReport();
        BeanUtils.copyProperties(labItemsReportPage, itemsRecordReport);
        LabItemsRecordReport labItemsRecordReport = labItemsRecordReportService.getById(itemsRecordReport.getId());
        String entrustType = labItemsReportPage.getEntrustType();
        List<LabEntrustItemsIndexPage> labEntrustItemsIndexList = labItemsReportPage.getLabEntrustItemsIndexPageList();
        itemsRecordReport.setBillStatus("待编辑");
        long time = new Date().getTime();
        List<LabCronJob> jobs = new ArrayList<>();
        jobs.add(new LabCronJob("lab_items_record_report", "0", time, 1));
        jobs.add(new LabCronJob("lab_entrust_items", "1", time, 2));
        if (labEntrustItemsIndexList != null && labEntrustItemsIndexList.size() > 0) {
            jobs.add(new LabCronJob("lab_entrust_items_index", "1", time, 3));
        }
        if (labItemsRecordReport == null) {
            labItemsRecordReportService.saveMain(itemsRecordReport, labEntrustItemsIndexList, entrustType);

            if ("委托检验".equals(entrustType)) {
                jobs.add(new LabCronJob("lab_wentrust", "1", time, 4));
            } else if ("监督检验".equals(entrustType)) {
                jobs.add(new LabCronJob("lab_wsupervise", "1", time, 5));
            }
        } else {
            labItemsRecordReportService.updateMain(itemsRecordReport, labEntrustItemsIndexList, entrustType);

            if ("委托检验".equals(entrustType)) {
                jobs.add(new LabCronJob("lab_wentrust", "1", time, 4));
            } else if ("监督检验".equals(entrustType)) {
                jobs.add(new LabCronJob("lab_wsupervise", "1", time, 5));
            }
        }
        if (MyEnum.sync) {
            labCronJobService.saveBatch(jobs);
        }
        /**
         * 线程
         */
        Callable<Boolean> c = () -> {
            try {
                //下载报告
                labWentrustController.downloadReportWord(labItemsReportPage.getTaskId(), labItemsReportPage.getEntrustType(), null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
        };
        threadExecutor.submit(c);
        String params = entrustType;
        String samName = labItemsReportPage.getSamName();
        String samNum = labItemsReportPage.getSamNum();
        String reportNumber = labItemsReportPage.getReportNum();
        String pdfFile = "/labPdf/" + samNum + "/" + samName + "-" + params + "-" + reportNumber + ".pdf";
        labItemsReportPage.setId(itemsRecordReport.getId());
        labItemsReportPage.setPfdFile(pdfFile);
        return Result.OK(labItemsReportPage);
    }

    @AutoLog(value = "实验报告-提交")
    @ApiOperation(value = "实验报告-提交", notes = "实验报告-提交")
    @RequestMapping(value = "/submitReportData", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> submitReportData(@RequestBody LabItemsReportPage labItemsReportPage) throws Exception {
        LabItemsRecordReport itemsRecordReport = new LabItemsRecordReport();
        BeanUtils.copyProperties(labItemsReportPage, itemsRecordReport);
        String entrustType = labItemsReportPage.getEntrustType();
        List<LabEntrustItemsIndexPage> labEntrustItemsIndexList = labItemsReportPage.getLabEntrustItemsIndexPageList();
        itemsRecordReport.setBillStatus("待审核");
        labItemsRecordReportService.updateMain(itemsRecordReport, labEntrustItemsIndexList, entrustType);

        //todo 更新样品状态
        String taskId = itemsRecordReport.getTaskId();
        labEntrustSampleService.updateSamByTaskId(taskId);

        //todo 暂时没有写同步数据操作  由于时间比较短可能导致同步数据标识出问题。
        labWentrustController.scReportPdf(taskId, entrustType);
        //生成消息
//        String notName = itemsRecordReport.getSamName();
//        String notStr ="样品[" + notName + "]的" + "报告审核";
//        if (notName == null || notName.isEmpty()) {
//            notStr = "实验报告审核";
//        }
//        String itemName = "";
//        String notTitle = "报告审核";
//        String taskName = notStr;
//        String entrustId = itemsRecordReport.getTaskId();
//        String userId = itemsRecordReport.getAuditId();
//        makeNotify(notName, itemName, notTitle, taskId, taskName, entrustId, userId);
        return Result.OK("报告提交完成!");
    }

    /**
     * 创建消息
     *
     * @param notName   消息名称
     * @param itemName  任务名称
     * @param notTitle  消息标题
     * @param taskId    任务id
     * @param taskName  消息名称（展示）
     * @param entrustId 业务id
     * @param uerId     处理人id
     */
    private void makeNotify(String notName, String itemName, String notTitle, String taskId, String taskName, String entrustId, String uerId) throws NoSuchAlgorithmException, IOException, InvalidKeyException {
        LabNotify labNotify = new LabNotify();
        labNotify.setNotName(notName);
        labNotify.setItemName(itemName);
        labNotify.setNotTitlle(notTitle);
        //todo:确认taskid是项目的id
        labNotify.setTaskId(taskId);
        labNotify.setTaskName(taskName);
        labNotify.setEntrustId(entrustId);
        labNotify.setUserId(uerId);
        labNotify.setNotStatus("未读");
        labNotify.setFinish(0);
        labNotify.setPubTime(new Date());
        labNotifyService.save(labNotify);
        /**
         * 线程
         */
        Callable<Boolean> c = () -> {
            try {
                //调即时通
                LoginUser loginUser = labNotifyService.byIdLogUser(uerId);
                //判断用户是否在数智天研系统中是否有账号，如果有发送消息，否则不发消息
                String tId = loginUser.getTId();
                if (!"".equals(tId) && tId != null) {
                    TokenServess tokenServess = new TokenServess();
                    String tokenServe = tokenServess.getTokenServe();
                    tokenServess.getSysmw(taskName, tId, tokenServe);
                }
            } catch (Exception e) {
            }
            return true;
        };
        threadExecutor.submit(c);
    }

    /**
     * 报告审核、批准（通过、不通过）
     *
     * @param id
     * @param billStatus
     * @return
     */
    @AutoLog(value = "实验报告-报告审核、批准（通过、不通过）")
    @ApiOperation(value = "实验报告-报告审核、批准（通过、不通过）", notes = "实验报告-报告审核、批准（通过、不通过）")
    @DeleteMapping(value = "/auditReportData")
    public Result<String> auditReportData(@RequestParam(name = "id", required = true) String id,
                                          @RequestParam(name = "billStatus", required = true) String billStatus,
                                          @RequestParam(name = "entrustType", required = true) String entrustType,
                                          @RequestParam(name = "reportConcl", defaultValue = "") String reportConcl,
                                          @RequestParam(name = "remark", defaultValue = "") String remark) throws Exception {
        LabItemsRecordReport labItemsRecordReport = labItemsRecordReportService.getById(id);
        //String entrustType = "委托检验";
        if (labItemsRecordReport == null) {
            return Result.error("未找到对应数据");
        }
        if (reportConcl != null && !"".equals(reportConcl)) {
            labItemsRecordReport.setReportConcl(reportConcl);
        }
        if (remark != null && !"".equals(remark) && !"null".equals(remark)) {
            labItemsRecordReport.setRemark(remark);
        }
        labItemsRecordReport.setBillStatus(billStatus);
        labItemsRecordReport.setSynFlag("1");
        labItemsRecordReportService.updateById(labItemsRecordReport);
        //下载报告
        Callable<Boolean> c = () -> {
            try {
                //下载报告
                labWentrustController.scReportPdf(labItemsRecordReport.getTaskId(), entrustType);
            } catch (Exception e) {
            }
            return true;
        };
        threadExecutor.submit(c);

        //生成消息
        String notName = labItemsRecordReport.getSamName();
        String itemName = "";
        String notTitle = "报告批准";
        String taskId = labItemsRecordReport.getTaskId();
        String taskName = "样品[" + notName + "]的" + "报告批准";
        String entrustId = labItemsRecordReport.getTaskId();
        String userId = labItemsRecordReport.getRatifyId();
        makeNotify(notName, itemName, notTitle, taskId, taskName, entrustId, userId);
        if (MyEnum.sync) {
            long time = new Date().getTime();
            LabCronJob job = new LabCronJob("lab_items_record_report", "1", time, 1);
            labCronJobService.save(job);
        }
        if ("待批准".equals(billStatus)) {
            return Result.OK("审核通过!");
        } else if ("下载".equals(billStatus)) {
            return Result.OK("批准通过!");
        } else if ("待审核".equals(billStatus)) {
            return Result.OK("批准不通过!");
        } else {
            return Result.OK("审核不通过!");
        }

    }


    /**
     * 导出excel
     *
     * @param request
     * @param labItemsRecordReport
     */
//    @RequiresPermissions("report:lab_items_record_report:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, LabItemsRecordReport labItemsRecordReport) {
        return super.exportXls(request, labItemsRecordReport, LabItemsRecordReport.class, "项目检测记录_实验报告");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
//    @RequiresPermissions("report:lab_items_record_report:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, LabItemsRecordReport.class);
    }

}
